/*
 * @(#)PanelResultInformation.java Jan 19, 2012 - 10:05:00 PM
 * 
 * Copyright 2011 Cin/UFPE/VSPEED
 */
package speed2010.andreza.vspeed.gui;

import java.awt.Component;
import java.awt.Container;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.LayoutStyle;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

import prefuse.Display;
import speed2010.andreza.vspeed.integration.CommunicationManager;
import speed2010.andreza.vspeed.integration.NodeGeneric;
import speed2010.andreza.vspeed.util.SwingUtils;
import speed2010.andreza.vspeed.view.ConsolidadorInfoPrefuse;
import speed2010.andreza.vspeed.view.PrefuseConstants;
import speed2010.reformulacao.query.InstanceResult;

/**
 * /**
 * 
 * @author <a href="mailto:andreza.lba@gmail.com">Andreza Leite de Alencar</a>
 */
public class PanelResultInformation extends JPanel {
	private static final long serialVersionUID = -8681977377344348614L;

	private JScrollPane jScrollPaneNetwork;
	private JTabbedPane jTabbedPaneResultInfo;
	private JEditorPane jEditorPaneLegend;

	private JPanel jPanelFeedback;
	private JPanel jPanelNetwork;
	private JPanel jPanelResultInformation;
	private JPanel jPanelResultNetworkLocation;

	private JProgressBar jProgressBarPlotNetwork;
	private JButton jButtonExit;

	private JLabel jLabelfeedback1;
	private JLabel jLabelAccept;
	private JLabel jLabelReject;

	private PanelTableResult jPanelTableResult;

	private ConsolidadorInfoPrefuse consolidadorInfoPrefuse;

	private final InstanceResult instanceResult;

	private final Object mutex = new Object();

	private boolean isTopologyPloted;

	public PanelResultInformation(final InstanceResult instanceResult) {
		super();
		this.instanceResult = instanceResult;
		initGUI();
	}

	/**
	 * Init the GUI components
	 */
	private void initGUI() {
		try {
			{
				final GroupLayout thisLayout = new GroupLayout(this);
				setLayout(thisLayout);
				setPreferredSize(new java.awt.Dimension(741, 471));
				{
					this.jTabbedPaneResultInfo = new JTabbedPane();
					this.jTabbedPaneResultInfo.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
					this.jTabbedPaneResultInfo.setBackground(new java.awt.Color(255, 255, 255));
					{
						this.jPanelResultInformation = new JPanel();
						this.jTabbedPaneResultInfo.addTab("Result Information", null, this.jPanelResultInformation,
								null);
						final GroupLayout jPanel1Layout = new GroupLayout(this.jPanelResultInformation);
						this.jPanelResultInformation.setLayout(jPanel1Layout);
						this.jPanelResultInformation.setPreferredSize(new java.awt.Dimension(562, 278));
						this.jPanelResultInformation.setBackground(new java.awt.Color(255, 255, 255));
						{
							this.jPanelTableResult = new PanelTableResult(this.instanceResult);
						}
						{
							this.jPanelFeedback = new JPanel();
							final GroupLayout jPanelFeedbackLayout = new GroupLayout(this.jPanelFeedback);
							this.jPanelFeedback.setLayout(jPanelFeedbackLayout);
							this.jPanelFeedback.setBackground(new java.awt.Color(255, 255, 255));
							{
								this.jLabelfeedback1 = new JLabel();
								this.jLabelfeedback1.setText("Give Your Feedback!");
								this.jLabelfeedback1.setFont(new java.awt.Font("Tahoma", 1, 12));
							}
							{
								this.jLabelAccept = new JLabel();
								this.jLabelAccept.setText("Accept Result");
								this.jLabelAccept.setIcon(GUIConstants.Images.ACCEPT_ICON);
								this.jLabelAccept.addMouseListener(new java.awt.event.MouseAdapter() {
						            @Override
									public void mouseClicked(java.awt.event.MouseEvent evt) {
						                SwingUtils.infoMessage(new JFrame(), "Feedback recorded with sucess!", "Info");
						            }
						        });
							}
							{
								this.jLabelReject = new JLabel();
								this.jLabelReject.setText("Reject Result");
								this.jLabelReject.setIcon(GUIConstants.Images.REJECT_ICON);
								this.jLabelReject.addMouseListener(new java.awt.event.MouseAdapter() {
						            @Override
									public void mouseClicked(java.awt.event.MouseEvent evt) {
						                SwingUtils.infoMessage(new JFrame(), "Feedback recorded with sucess!", "Info");
						            }
						        });
								
							}
							jPanelFeedbackLayout.setHorizontalGroup(jPanelFeedbackLayout
									.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											jPanelFeedbackLayout
													.createParallelGroup()
													.addGroup(
															GroupLayout.Alignment.LEADING,
															jPanelFeedbackLayout
																	.createSequentialGroup()
																	.addComponent(this.jLabelReject,
																			GroupLayout.PREFERRED_SIZE, 116,
																			GroupLayout.PREFERRED_SIZE)
																	.addGap(0, 16, Short.MAX_VALUE))
													.addGroup(
															GroupLayout.Alignment.LEADING,
															jPanelFeedbackLayout
																	.createSequentialGroup()
																	.addComponent(this.jLabelAccept, 0, 116,
																			Short.MAX_VALUE).addGap(16))
													.addComponent(this.jLabelfeedback1, GroupLayout.Alignment.LEADING,
															0, 132, Short.MAX_VALUE)));
							jPanelFeedbackLayout.linkSize(SwingConstants.HORIZONTAL, new Component[]{this.jLabelAccept,
									this.jLabelReject});
							jPanelFeedbackLayout.setVerticalGroup(jPanelFeedbackLayout
									.createSequentialGroup()
									.addContainerGap()
									.addComponent(this.jLabelfeedback1, GroupLayout.PREFERRED_SIZE, 35,
											GroupLayout.PREFERRED_SIZE)
									.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
									.addComponent(this.jLabelAccept, GroupLayout.PREFERRED_SIZE, 32,
											GroupLayout.PREFERRED_SIZE)
									.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
									.addComponent(this.jLabelReject, GroupLayout.PREFERRED_SIZE, 32,
											GroupLayout.PREFERRED_SIZE).addContainerGap(250, Short.MAX_VALUE));
							jPanelFeedbackLayout.linkSize(SwingConstants.VERTICAL, new Component[]{this.jLabelAccept,
									this.jLabelReject});
						}
						jPanel1Layout
								.setVerticalGroup(jPanel1Layout
										.createParallelGroup()
										.addComponent(this.jPanelTableResult, GroupLayout.Alignment.LEADING, 0, 397,
												Short.MAX_VALUE)
										.addGroup(
												GroupLayout.Alignment.LEADING,
												jPanel1Layout.createSequentialGroup()
														.addComponent(this.jPanelFeedback, 0, 373, Short.MAX_VALUE)
														.addGap(30)));
						jPanel1Layout.setHorizontalGroup(jPanel1Layout
								.createSequentialGroup()
								.addComponent(this.jPanelTableResult, 0, 566, Short.MAX_VALUE)
								.addGap(8)
								.addComponent(this.jPanelFeedback, GroupLayout.PREFERRED_SIZE, 142,
										GroupLayout.PREFERRED_SIZE));
					}
					{
						this.jPanelResultNetworkLocation = new JPanel();
						final GroupLayout jPanelResultNetworkLocationLayout = new GroupLayout(
								this.jPanelResultNetworkLocation);
						this.jPanelResultNetworkLocation.setLayout(jPanelResultNetworkLocationLayout);
						this.jPanelResultNetworkLocation.addComponentListener(new java.awt.event.ComponentAdapter() {
							@Override
							public void componentShown(final java.awt.event.ComponentEvent evt) {
								drawTopologyMap();
							}
						});

						this.jTabbedPaneResultInfo.addTab("Result Network Location", null,
								this.jPanelResultNetworkLocation, null);
						this.jPanelResultNetworkLocation.setBackground(new java.awt.Color(255, 255, 255));
						this.jPanelResultNetworkLocation.setPreferredSize(new java.awt.Dimension(716, 418));
						{
							this.jProgressBarPlotNetwork = getProgressBar();
							this.jProgressBarPlotNetwork.setOpaque(true);
							this.jProgressBarPlotNetwork.setBackground(new java.awt.Color(255, 255, 255));
						}
						{
							this.jScrollPaneNetwork = new JScrollPane();
							this.jScrollPaneNetwork.setBackground(new java.awt.Color(255, 255, 255));
							this.jScrollPaneNetwork.setLocale(new java.util.Locale("en", "GB"));
							this.jScrollPaneNetwork.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
							{
								this.jPanelNetwork = new JPanel();
								this.jScrollPaneNetwork.setViewportView(this.jPanelNetwork);
								this.jPanelNetwork.setPreferredSize(new java.awt.Dimension(597, 360));
								this.jPanelNetwork.setBackground(new java.awt.Color(255, 255, 255));
							}
						}
						{
							this.jEditorPaneLegend = getJEditorPane();
						}
						jPanelResultNetworkLocationLayout.setHorizontalGroup(jPanelResultNetworkLocationLayout
								.createParallelGroup()
								.addGroup(
										GroupLayout.Alignment.LEADING,
										jPanelResultNetworkLocationLayout
												.createSequentialGroup()
												.addComponent(this.jScrollPaneNetwork, GroupLayout.PREFERRED_SIZE, 597,
														GroupLayout.PREFERRED_SIZE)
												.addGap(0, 0, Short.MAX_VALUE)
												.addComponent(this.jEditorPaneLegend, GroupLayout.PREFERRED_SIZE, 109,
														GroupLayout.PREFERRED_SIZE).addContainerGap())
								.addGroup(
										GroupLayout.Alignment.LEADING,
										jPanelResultNetworkLocationLayout
												.createSequentialGroup()
												.addPreferredGap(this.jScrollPaneNetwork, this.jProgressBarPlotNetwork,
														LayoutStyle.ComponentPlacement.INDENT)
												.addComponent(this.jProgressBarPlotNetwork, 0, 696, Short.MAX_VALUE)
												.addContainerGap()));
						jPanelResultNetworkLocationLayout.setVerticalGroup(jPanelResultNetworkLocationLayout
								.createSequentialGroup()
								.addGroup(
										jPanelResultNetworkLocationLayout
												.createParallelGroup()
												.addComponent(this.jScrollPaneNetwork, GroupLayout.Alignment.LEADING,
														0, 364, Short.MAX_VALUE)
												.addGroup(
														GroupLayout.Alignment.LEADING,
														jPanelResultNetworkLocationLayout
																.createSequentialGroup()
																.addComponent(this.jEditorPaneLegend,
																		GroupLayout.PREFERRED_SIZE, 131,
																		GroupLayout.PREFERRED_SIZE).addGap(233)))
								.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 0, GroupLayout.PREFERRED_SIZE)
								.addComponent(this.jProgressBarPlotNetwork, GroupLayout.PREFERRED_SIZE, 16,
										GroupLayout.PREFERRED_SIZE).addContainerGap());
					}
				}
				{
					this.jButtonExit = new JButton();
					this.jButtonExit.setText("Exit");
					this.jButtonExit.addActionListener(new java.awt.event.ActionListener() {
						@Override
						public void actionPerformed(final java.awt.event.ActionEvent evt) {
							closeFrame();
						}
					});

				}
				thisLayout.setVerticalGroup(thisLayout
						.createSequentialGroup()
						.addGap(6)
						.addComponent(this.jTabbedPaneResultInfo, 0, 425, Short.MAX_VALUE)
						.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
						.addComponent(this.jButtonExit, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE,
								GroupLayout.PREFERRED_SIZE).addContainerGap());
				thisLayout.setHorizontalGroup(thisLayout
						.createSequentialGroup()
						.addContainerGap()
						.addGroup(
								thisLayout
										.createParallelGroup()
										.addComponent(this.jTabbedPaneResultInfo, GroupLayout.Alignment.LEADING, 0,
												721, Short.MAX_VALUE)
										.addGroup(
												GroupLayout.Alignment.LEADING,
												thisLayout
														.createSequentialGroup()
														.addGap(625, 625, 625)
														.addComponent(this.jButtonExit, GroupLayout.PREFERRED_SIZE, 87,
																GroupLayout.PREFERRED_SIZE).addGap(9)))
						.addContainerGap());
			}
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	private JEditorPane getJEditorPane() {
		if (this.jEditorPaneLegend == null) {
			this.jEditorPaneLegend = new JEditorPane();
			this.jEditorPaneLegend.setContentType("text/html");
			this.jEditorPaneLegend.setEditable(false);
			this.jEditorPaneLegend.setBorder(BorderFactory.createTitledBorder("Legend"));
			this.jEditorPaneLegend.setBackground(new java.awt.Color(255, 255, 255));

			this.jEditorPaneLegend.setText(buildLegend());
		}

		return this.jEditorPaneLegend;
	}

	private String buildLegend() {
		final String nodeSource = Integer.toHexString(PrefuseConstants.NODE_RESULT_SOURCE & 0x00ffffff);
		final String nodes = Integer.toHexString(PrefuseConstants.NODE_RESULT_PEERS & 0x00ffffff);
		final String nodeSubmit = Integer.toHexString(PrefuseConstants.NODE_COLOR_SEARCH & 0x00ffffff);

		final StringBuilder sb = new StringBuilder();
		sb.append("<html><body>");
		sb.append("<table>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeSubmit).append("\" width=\"9px\"/>");
		sb.append("<td>Your Location</td>");
		sb.append("</tr>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodeSource).append("\" width=\"9px\"/>");
		sb.append("<td>Origin Peer</td>");
		sb.append("</tr>");
		sb.append("<tr>");
		sb.append("<td bgcolor=\"").append(nodes).append("\"/>");
		sb.append("<td>Clusters</td>");
		sb.append("</tr>");
		sb.append("</body></html");

		return sb.toString();
	}
	private void drawTopologyMap() {
		if (!this.isTopologyPloted) {
			this.jProgressBarPlotNetwork.setIndeterminate(true);

			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						Thread.sleep(3000);
					} catch (final InterruptedException e) {
						e.printStackTrace();
					}
					final CommunicationManager manager = CommunicationManager.getInstance();
					manager.recoveryTopologyInfo();

					final NodeGeneric genericPeer = manager.getGenericPeer();

					final Display d = PanelResultInformation.this.consolidadorInfoPrefuse.gerarDisplay(
							genericPeer.getMapAddressReduzido_NodeInfo(), true, true);
					PanelResultInformation.this.jPanelNetwork.removeAll();
					PanelResultInformation.this.jPanelNetwork.add(d);

					synchronized (PanelResultInformation.this.mutex) {
						PanelResultInformation.this.mutex.notify();
					}
				}
			}).start();

			new Thread(new Runnable() {
				@Override
				public void run() {
					synchronized (PanelResultInformation.this.mutex) {
						try {
							PanelResultInformation.this.mutex.wait();
							PanelResultInformation.this.jProgressBarPlotNetwork.setIndeterminate(false);
							PanelResultInformation.this.isTopologyPloted = true;
						} catch (final InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}).start();
		}
	}

	/**
	 * @return
	 */
	private JProgressBar getProgressBar() {
		if (this.jProgressBarPlotNetwork == null) {
			this.jProgressBarPlotNetwork = new JProgressBar();
		}

		return this.jProgressBarPlotNetwork;
	}

	public void updateProgessBar(final int newValue) {
		this.jProgressBarPlotNetwork.setValue(newValue);
	}

	/**
	 * Prepare the results information and map result information
	 */
	public void initializeTopology(final String selectValue) {
		final Runnable plotaTopologia = new Runnable() {
			@Override
			public void run() {
				PanelResultInformation.this.consolidadorInfoPrefuse = new ConsolidadorInfoPrefuse(selectValue);
				final CommunicationManager manager = CommunicationManager.getInstance();
				manager.sendPrepareTopolyMessage();
			}
		};

		final Thread tPlotaTopologia = new Thread(plotaTopologia);
		tPlotaTopologia.start();
	}

	public void formWindowClosed(final java.awt.event.WindowEvent evt) {
		GUIConstants.GUI_INSTANCE.setEnabled(true);
	}

	/**
	 * Close the current frame where the panel is located
	 */
	private void closeFrame() {
		Container Frame = this.jButtonExit.getParent();
		do {
			Frame = Frame.getParent();
		} while (!(Frame instanceof JFrame));
		((JFrame) Frame).dispose();

		GUIConstants.GUI_INSTANCE.setEnabled(true);
	}

	/**
	 * User only to preview the form design
	 * 
	 * @param args
	 */
	public static void main(final String[] args) {
		final JFrame frameResultInfo = new JFrame();
		final PanelResultInformation panelResultInformation = new PanelResultInformation(null);
		frameResultInfo.getContentPane().add(panelResultInformation);
		frameResultInfo.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frameResultInfo.pack();
		frameResultInfo.setLocationRelativeTo(frameResultInfo.getRootPane());
		frameResultInfo.setVisible(true);
	}
}
